package com.hzncc.flowable_diboot.project_contracts.controller;

import com.diboot.core.binding.Binder;
import com.diboot.core.controller.BaseCrudRestController;
import com.diboot.core.util.S;
import com.diboot.core.vo.JsonResult;
import com.diboot.core.vo.Pagination;
import com.diboot.file.util.FileHelper;
import com.diboot.file.util.HttpHelper;
import com.diboot.iam.annotation.BindPermission;
import com.diboot.iam.annotation.Log;
import com.diboot.iam.annotation.OperationCons;
import com.diboot.iam.util.IamSecurityUtils;
import com.hzncc.flowable_diboot.enums.ContractAuditStatusEnum;
import com.hzncc.flowable_diboot.enums.ContractAuditTypeEnum;
import com.hzncc.flowable_diboot.excel.model.CustomerOldCrmImportModel;
import com.hzncc.flowable_diboot.project_contracts.dto.ProjectContractAuditDTO;
import com.hzncc.flowable_diboot.project_contracts.entity.ProjectContractAudit;
import com.hzncc.flowable_diboot.project_contracts.entity.ProjectContractItem;
import com.hzncc.flowable_diboot.project_contracts.service.ProjectContractAuditService;
import com.hzncc.flowable_diboot.project_contracts.vo.ProjectContractAuditDetailVO;
import com.hzncc.flowable_diboot.project_contracts.vo.ProjectContractAuditListVO;
import com.hzncc.flowable_diboot.project_contracts.vo.ProjectContractCancelDetailVO;
import com.hzncc.flowable_diboot.project_contracts.vo.ProjectDiffVO;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.util.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 项目类合同评审 相关rest接口
 *
 * @author MyName
 * @version 1.0
 * @date 2024-09-24
 * Copyright © MyCorp
 */
@Slf4j
@RequestMapping("/project-contract-audit")
@BindPermission(name = "项目类合同评审")
@RestController
public class ProjectContractAuditController extends BaseCrudRestController<ProjectContractAudit> {

    @Autowired
    private ProjectContractAuditService projectContractAuditService;

    /**
     * 查询资源对象的列表VO记录
     * <p>
     * url请求参数示例: ?fieldA=abc&pageSize=20&pageIndex=1&orderBy=id
     * </p>
     *
     * @return
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_LIST)
    @BindPermission(name = OperationCons.LABEL_LIST, code = OperationCons.CODE_READ)
    @GetMapping()
    public JsonResult<List<ProjectContractAuditListVO>> getListVOMapping(ProjectContractAuditDTO queryDto, String type, String permission, Pagination pagination) throws Exception {
        return projectContractAuditService.selectContractAudit(queryDto, pagination, type, permission);
    }

    /**
     * 根据id查询资源对象的详情VO
     *
     * @param id ID
     * @return
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_DETAIL)
    @BindPermission(name = OperationCons.LABEL_DETAIL, code = OperationCons.CODE_READ)
    @GetMapping("/{id}")
    public JsonResult<ProjectContractAuditDetailVO> getDetailVOMapping(@PathVariable("id") String id) throws Exception {
        ProjectContractAuditDetailVO detailVO = projectContractAuditService.getViewObject(id, ProjectContractAuditDetailVO.class);
        Binder.bindRelations(detailVO);
        return JsonResult.OK(detailVO);
    }


    /**
     * 创建资源对象数据
     *
     * @param projectContractAudit
     * @return JsonResult
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_CREATE)
    @BindPermission(name = OperationCons.LABEL_CREATE, code = OperationCons.CODE_WRITE)
    @PostMapping()
    public JsonResult<?> createModelMapping(@RequestBody ProjectContractAudit projectContractAudit) throws Exception {
        boolean success = projectContractAuditService.createEntity(projectContractAudit);
        log.debug("新建数据 项目类合同评审:{} {}", projectContractAudit.getId(), success ? "成功" : "失败");
        return JsonResult.OK(projectContractAudit.getId());
    }

    /**
     * 批量创建资源对象数据
     *
     * @param projectContractAuditList
     * @return JsonResult
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_BATCH_UPDATE)
    @BindPermission(name = OperationCons.LABEL_UPDATE, code = OperationCons.CODE_WRITE)
    @PostMapping("/batch")
    public JsonResult<?> batchCreateModelMapping(@RequestBody List<ProjectContractAudit> projectContractAuditList) throws Exception {
        boolean success = projectContractAuditService.createEntities(projectContractAuditList);
        log.debug("批量新建数据 项目类合同评审 {}", success ? "成功" : "失败");
        return JsonResult.OK(success);
    }

    /**
     * 根据id更新资源对象
     *
     * @param projectContractAudit
     * @return JsonResult
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_UPDATE)
    @BindPermission(name = OperationCons.LABEL_UPDATE, code = OperationCons.CODE_WRITE)
    @PutMapping("/{id}")
    public JsonResult<?> updateModelMapping(@PathVariable("id") String id, @RequestBody ProjectContractAudit projectContractAudit) throws Exception {
        boolean success = projectContractAuditService.updateEntity(projectContractAudit);
        log.debug("更新数据 项目类合同评审:{} {}", id, success ? "成功" : "失败");
        return JsonResult.OK(success);
    }

    /**
     * 根据id删除资源对象
     *
     * @param id
     * @return
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_DELETE)
    @BindPermission(name = OperationCons.LABEL_DELETE, code = OperationCons.CODE_WRITE)
    @DeleteMapping("/{id}")
    public JsonResult<?> deleteModelMapping(@PathVariable("id") String id) throws Exception {
        projectContractAuditService.delete(id);
        return JsonResult.OK();
    }

    /**
     * 根据ids集合删除资源对象
     *
     * @param ids
     * @return
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_BATCH_DELETE)
    @BindPermission(name = OperationCons.LABEL_DELETE, code = OperationCons.CODE_WRITE)
    @PostMapping("/batch-delete")
    public JsonResult<?> deleteEntityMapping(@RequestBody List<String> ids) throws Exception {
        boolean success = projectContractAuditService.deleteEntities(ids);
        log.debug("批量删除数据 项目类合同评审:{} {}", ids, success ? "成功" : "失败");
        return JsonResult.OK(success);
    }

    /**
     * 保存项目类合同评审
     *
     * @param projectContractAudit
     * @return
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_CREATE)
    @BindPermission(name = OperationCons.LABEL_CREATE, code = OperationCons.CODE_WRITE)
    @PostMapping("/save")
    public JsonResult<String> saveProjectContractAudit(@RequestBody ProjectContractAuditDetailVO projectContractAudit) throws Exception {
        projectContractAudit.setContractStatus(ContractAuditStatusEnum.NO_SUBMIT.getCode()).setAuditType("create");
        String id = projectContractAuditService.saveProjectContractAudit(projectContractAudit);
        return JsonResult.OK(id);
    }

    /**
     * 提交项目类合同评审
     *
     * @param projectContractAudit
     * @return
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_CREATE)
    @BindPermission(name = OperationCons.LABEL_CREATE, code = OperationCons.CODE_WRITE)
    @PostMapping("/submit")
    public JsonResult<String> submitProjectContractAudit(@RequestBody ProjectContractAuditDetailVO projectContractAudit) throws Exception {
        projectContractAudit.setContractStatus(ContractAuditStatusEnum.PROCESSING.getCode()).setAuditType("create");
        return JsonResult.OK(projectContractAuditService.submitProjectContractAudit(projectContractAudit));
    }

    /**
     * 复制项目类合同评审
     *
     * @param id
     * @return
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_CREATE)
    @BindPermission(name = OperationCons.LABEL_CREATE, code = OperationCons.CODE_WRITE)
    @GetMapping("/copy/{id}")
    public JsonResult<?> copyProjectContractAudit(@PathVariable String id) throws Exception {
        ProjectContractAuditDetailVO contractAuditDetailVO = projectContractAuditService.copyProjectContractAudit(id);
        contractAuditDetailVO.setContractVersion(1L);
        return JsonResult.OK(contractAuditDetailVO);
    }

    /**
     * 变更项目类合同评审
     *
     * @param projectContractAudit
     * @return
     */
    @Log(operation = OperationCons.LABEL_CREATE)
    @BindPermission(name = OperationCons.LABEL_CREATE, code = OperationCons.CODE_WRITE)
    @PostMapping("/submit_change")
    public JsonResult<String> changeOfContract(@RequestBody ProjectContractAuditDetailVO projectContractAudit) throws Exception {
        JsonResult<String> res = projectContractAuditService.changeOfContract(projectContractAudit, true);
        return res;
    }

    /**
     * 暂存变更项目类合同评审
     *
     * @param projectContractAudit
     * @return
     */
    @Log(operation = OperationCons.LABEL_CREATE)
    @BindPermission(name = OperationCons.LABEL_CREATE, code = OperationCons.CODE_WRITE)
    @PostMapping("/save_change")
    public JsonResult<?> saveChangeOfContract(@RequestBody ProjectContractAuditDetailVO projectContractAudit) throws Exception {
        JsonResult<String> res = projectContractAuditService.changeOfContract(projectContractAudit, false);
        return res;
    }

    /**
     * 获取变更项目类合同评审详情
     *
     * @param id
     * @return
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_DETAIL)
    @BindPermission(name = OperationCons.LABEL_DETAIL, code = OperationCons.CODE_READ)
    @GetMapping("/getUpdateDetail/{id}")
    public JsonResult<?> getUpdateDetail(@PathVariable String id) throws Exception {
        return projectContractAuditService.getUpdateDetail(id);
    }

    /**
     * 归档项目类合同评审
     *
     * @param id
     * @return
     */
    @Log(operation = OperationCons.LABEL_UPDATE)
    @BindPermission(name = OperationCons.LABEL_UPDATE, code = OperationCons.CODE_WRITE)
    @PutMapping("/archiving/{id}")
    public JsonResult<?> archiving(@PathVariable String id) {
        return projectContractAuditService.archiving(id);
    }

    /**
     * 取消归档项目类合同评审
     *
     * @param id
     * @return
     */
    @Log(operation = OperationCons.LABEL_UPDATE)
    @BindPermission(name = OperationCons.LABEL_UPDATE, code = OperationCons.CODE_WRITE)
    @PutMapping("/unarchive/{id}")
    public JsonResult<?> cancelArchiving(@PathVariable String id) {
        return projectContractAuditService.cancelArchiving(id);
    }


    /**
     * 暂存取消项目类合同评审
     *
     * @param projectContractCancel
     * @return
     */
    @Log(operation = OperationCons.LABEL_CREATE)
    @BindPermission(name = OperationCons.LABEL_CREATE, code = OperationCons.CODE_WRITE)
    @PostMapping("/save_cancel")
    public JsonResult<?> saveCancel(@RequestBody ProjectContractCancelDetailVO projectContractCancel) {
        return projectContractAuditService.cancelContract(projectContractCancel, false);
    }

    /**
     * 提交取消项目类合同评审
     *
     * @param projectContractCancel
     * @return
     */
    @Log(operation = OperationCons.LABEL_CREATE)
    @BindPermission(name = OperationCons.LABEL_CREATE, code = OperationCons.CODE_WRITE)
    @PostMapping("/submit_cancel")
    public JsonResult<?> cancelContract(@RequestBody ProjectContractCancelDetailVO projectContractCancel) {
        return projectContractAuditService.cancelContract(projectContractCancel, true);
    }

    /**
     * 比较项目类合同评审
     *
     * @param projectContractAudit
     * @return
     */
    @Log(operation = OperationCons.LABEL_DETAIL)
    @BindPermission(name = OperationCons.LABEL_DETAIL, code = OperationCons.CODE_READ)
    @PostMapping("/compare/{id}")
    public JsonResult<?> compareChange(@RequestBody ProjectContractAuditDetailVO projectContractAudit, @PathVariable String id) {
        return JsonResult.OK(projectContractAuditService.compareChange(projectContractAudit, id));
    }

    /**
     * 比较项目类合同评审
     *
     * @param id
     * @return
     */
    @Log(operation = OperationCons.LABEL_DETAIL)
    @BindPermission(name = OperationCons.LABEL_DETAIL, code = OperationCons.CODE_READ)
    @GetMapping("/compare/{id}")
    public JsonResult<?> compareChange(@PathVariable String id) {
        return JsonResult.OK(projectContractAuditService.compareChange(id));
    }

    /**
     * 收藏项目类合同评审
     *
     * @param id 项目类合同评审ID
     * @return JsonResult
     */
    @Log(operation = OperationCons.LABEL_UPDATE)
    @BindPermission(name = OperationCons.LABEL_UPDATE, code = OperationCons.CODE_WRITE)
    @PutMapping("/star/{id}")
    public JsonResult<?> starOrCancel(@PathVariable String id) {
        ProjectContractAuditListVO contract = projectContractAuditService.getViewObject(id, ProjectContractAuditListVO.class);
        List<String> starUids = contract.getStarUids() == null ? new ArrayList<>() : contract.getStarUids();
        String userId = IamSecurityUtils.getCurrentUserId();
        // 取关
        if (starUids.contains(userId)) {
            starUids.remove(userId);
        } else {
            starUids.add(userId);
        }
        contract.setStarUids(starUids);
        projectContractAuditService.updateEntity(contract);
        return JsonResult.OK();
    }


    /**
     * 获取项目类合同评审历史记录
     *
     * @param code       合同编码
     * @param pagination 分页
     * @return
     */
    @Log(operation = OperationCons.LABEL_LIST)
    @BindPermission(name = OperationCons.LABEL_LIST, code = OperationCons.CODE_READ)
    @GetMapping("/history")
    public JsonResult<?> getHistory(String code, Pagination pagination) {
        return JsonResult.OK(projectContractAuditService.getHistory(code, pagination));
    }


    @GetMapping("/pushOA/{id}")
    public JsonResult<?> pushOA(@PathVariable String id, String type) {
        ProjectContractAuditDetailVO contract = projectContractAuditService.getViewObject(id, ProjectContractAuditDetailVO.class);
        if (contract == null) {
            return JsonResult.FAIL_EXCEPTION("合同不存在");
        }
        if (S.equals(contract.getAuditType(), ContractAuditTypeEnum.UPDATE.getCode())) {
            Map<String, Object> diffMap = projectContractAuditService.compareChange(contract);
            contract.setDiffVOS((List<ProjectDiffVO>) diffMap.get("item"));
            List<Map<String,Object>> list = new ArrayList<>();
            list.add((Map<String, Object>) diffMap.get("contract"));
            contract.setExtendedProperties((Map<String, Object>) diffMap.get("contract"));
            contract.setAmountList(list);
//            List<ProjectDiffVO> diffVOS = contract.getDiffVOS();
//            contract.setAddList(diffVOS.stream().filter(item -> item.getAfterRemark().equals("新增")).map(e-> new ProjectContractItem()).collect(Collectors.toList()));
//            contract.setAddList(diffVOS.stream().filter(item -> item.getBeforeRemark().equals("删除")).map(e-> new ProjectContractItem()).collect(Collectors.toList()));
        }
        projectContractAuditService.pushOa(contract, type);
        contract.setStatus("1"); // 进行中
        return JsonResult.OK();
    }

    @GetMapping("/printWord/{id}")
    public JsonResult<?> printWord(HttpServletResponse response, @PathVariable String id) throws Exception {
        String filePath = projectContractAuditService.printWord(id);
        File file = new File(filePath);
        if (!file.exists()) {
            return JsonResult.FAIL_OPERATION("文件不存在");
        }
        HttpHelper.downloadLocalFile(file, file.getName(), response);
        return null;
    }

    @PostMapping("/import")
    public JsonResult<?> importHistoryData(@RequestParam("file") MultipartFile file, @RequestParam Map<String, Object> params) throws Exception {
        String fileName = file.getOriginalFilename();
        if (!fileName.endsWith(".xlsx")) {
            return JsonResult.FAIL_OPERATION("文件格式错误");
        }
        List<?> list = null;
        try {
            list = projectContractAuditService.importHistoryData(file, params);
        } catch (IOException | InstantiationException | IllegalAccessException e) {
            return JsonResult.FAIL_OPERATION("文件导入失败");
        }
        return JsonResult.OK(list);
    }
}